using Microsoft.Extensions.Caching.Memory;
using SqlSugar;

namespace Digitalmes.Infrastructure.Data;

/// <summary>
/// 基于内存的 Sugar 二级缓存。
/// </summary>
internal sealed class SqlSugarMemoryCache(IMemoryCache memoryCache) : ISqlSugarCache
{
    public bool ContainsKey<V>(string key)
    {
        if (memoryCache is not MemoryCache memoryCache2)
        {
            throw new NotSupportedException();
        }

        return memoryCache2.Keys.Contains(key);
    }

    public V? Get<V>(string key)
    {
        return memoryCache.Get<V>(key);
    }

    public IEnumerable<string> GetAllKey<V>()
    {
        if (memoryCache is not MemoryCache memoryCache2)
        {
            throw new NotSupportedException();
        }

        // 其中，"SqlSugarDataCache." 为 SqlSugar 二级缓存固定前缀
        return memoryCache2.Keys
                 .Where(k => k is string key && key.StartsWith("SqlSugarDataCache."))
                 .Select(key => (string)key);
    }

    public V? GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue)
    {
        return memoryCache.GetOrCreate(cacheKey, entry =>
        {
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(cacheDurationInSeconds);
            return create();
        });
    }

    public void Add<V>(string key, V value)
    {
        memoryCache.Set(key, value);
    }

    public void Add<V>(string key, V value, int cacheDurationInSeconds)
    {
        memoryCache.Set(key, value, DateTimeOffset.Now.AddSeconds(cacheDurationInSeconds));
    }

    public void Remove<V>(string key)
    {
        memoryCache.Remove(key);
    }
}
